#include "io.h"
#include "fsl_iomuxc.h"
#include "fsl_gpio.h"

//input
#define  INPUT_STOP_FUN    IOMUXC_GPIO_AD_B0_10_GPIO1_IO10
#define  INPUT_STOP_PORT   GPIO1
#define  INPUT_STOP_PIN    10u
#define  INPUT_STOP_IRQ    GPIO1_Combined_0_15_IRQn

#define  INPUT_REC_FUN     IOMUXC_GPIO_AD_B0_09_GPIO1_IO09
#define  INPUT_REC_PORT    GPIO1
#define  INPUT_REC_PIN     9u
#define  INPUT_REC_IRQ     GPIO1_Combined_0_15_IRQn

#define  INPUT_SAVE_FUN    IOMUXC_GPIO_B1_12_GPIO2_IO28
#define  INPUT_SAVE_PORT   GPIO2
#define  INPUT_SAVE_PIN    28u
#define  INPUT_SAVE_IRQ    GPIO2_Combined_16_31_IRQn

#define  INPUT_EXT_1_FUN   IOMUXC_GPIO_SD_B1_00_GPIO3_IO00
#define  INPUT_EXT_1_PORT  GPIO3
#define  INPUT_EXT_1_PIN   0u
#define  INPUT_EXT_1_IRQ   GPIO3_Combined_0_15_IRQn

#define  INPUT_EXT_2_FUN   IOMUXC_GPIO_SD_B1_01_GPIO3_IO01
#define  INPUT_EXT_2_PORT  GPIO3
#define  INPUT_EXT_2_PIN   1u
#define  INPUT_EXT_2_IRQ   GPIO3_Combined_0_15_IRQn

//output
#define  OUTPUT_MUTE_FUN    IOMUXC_GPIO_AD_B0_08_GPIO1_IO08
#define  OUTPUT_MUTE_PORT   GPIO1
#define  OUTPUT_MUTE_PIN    8u

#define  OUTPUT_RL_L_FUN    IOMUXC_GPIO_B1_03_GPIO2_IO19
#define  OUTPUT_RL_L_PORT   GPIO2
#define  OUTPUT_RL_L_PIN    19

#define  OUTPUT_RL_R_FUN    IOMUXC_GPIO_B1_01_GPIO2_IO17
#define  OUTPUT_RL_R_PORT   GPIO2
#define  OUTPUT_RL_R_PIN    17


__IO static uint32_t inputJump;
__IO static uint32_t inputPressed;
__IO static uint32_t inputState;

void ioInit(void)
{
//input
    const  gpio_pin_config_t  gpio_pin_input_config  =  {
            .direction      =  kGPIO_DigitalInput,
            .outputLogic    =  0U,
            .interruptMode  =  kGPIO_NoIntmode
//            .interruptMode  =  kGPIO_IntRisingOrFallingEdge
    };

    IOMUXC_SetPinMux(INPUT_EXT_1_FUN, 0U);
    IOMUXC_SetPinConfig(INPUT_EXT_1_FUN, GPIO_INPUT_CONFIG);

    IOMUXC_SetPinMux(INPUT_EXT_2_FUN, 0U);
    IOMUXC_SetPinConfig(INPUT_EXT_2_FUN, GPIO_INPUT_CONFIG);

    IOMUXC_SetPinMux(INPUT_STOP_FUN, 0U);
    IOMUXC_SetPinConfig(INPUT_STOP_FUN, GPIO_INPUT_CONFIG);

    IOMUXC_SetPinMux(INPUT_REC_FUN, 0U);
    IOMUXC_SetPinConfig(INPUT_REC_FUN, GPIO_INPUT_CONFIG);

    IOMUXC_SetPinMux(INPUT_SAVE_FUN, 0U);
    IOMUXC_SetPinConfig(INPUT_SAVE_FUN, GPIO_INPUT_CONFIG);

    GPIO_PinInit(INPUT_STOP_PORT, INPUT_STOP_PIN, &gpio_pin_input_config);
    GPIO_PinInit(INPUT_REC_PORT, INPUT_REC_PIN, &gpio_pin_input_config);
    GPIO_PinInit(INPUT_SAVE_PORT, INPUT_SAVE_PIN, &gpio_pin_input_config);
    GPIO_PinInit(INPUT_EXT_1_PORT, INPUT_EXT_1_PIN, &gpio_pin_input_config);
    GPIO_PinInit(INPUT_EXT_2_PORT, INPUT_EXT_2_PIN, &gpio_pin_input_config);

//output
    gpio_pin_config_t  gpio_pin_output_config  =  {
            .direction      =  kGPIO_DigitalOutput,
            .outputLogic    =  1U,
            .interruptMode  =  kGPIO_NoIntmode
    };
    IOMUXC_SetPinMux(OUTPUT_MUTE_FUN, 0U);
    IOMUXC_SetPinConfig(OUTPUT_MUTE_FUN, GPIO_OUTPUT_CONFIG);

    IOMUXC_SetPinMux(OUTPUT_RL_L_FUN, 0U);
    IOMUXC_SetPinConfig(OUTPUT_RL_L_FUN, GPIO_OUTPUT_CONFIG);

    IOMUXC_SetPinMux(OUTPUT_RL_R_FUN, 0U);
    IOMUXC_SetPinConfig(OUTPUT_RL_R_FUN, GPIO_OUTPUT_CONFIG);

    GPIO_PinInit(OUTPUT_MUTE_PORT, OUTPUT_MUTE_PIN, &gpio_pin_output_config);
    gpio_pin_output_config.outputLogic = 0;
    GPIO_PinInit(OUTPUT_RL_L_PORT, OUTPUT_RL_L_PIN, &gpio_pin_output_config);
    GPIO_PinInit(OUTPUT_RL_R_PORT, OUTPUT_RL_R_PIN, &gpio_pin_output_config);

    inputState = 0 ;

    for(int i=0; i<10; i++)
    {
        ioCheck();
        SDK_DelayAtLeastUs(5000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
    }
    inputJump = 0;
    inputPressed = 0 ;
}

void ioCheck(void)
{
    static uint32_t same = 0 ;
    static uint32_t lastState = 0xFFFFFFFF;
    static uint32_t sameCheck = 0;

    volatile uint32_t in,io1,io2,ch;

    in  = (INPUT_STOP_PORT->DR & (1ul << INPUT_STOP_PIN)) > 0 ? 1ul : 0ul;//4
    in <<= 1;
    in |= (INPUT_REC_PORT->DR & (1ul << INPUT_REC_PIN)) > 0 ? 1ul : 0ul;//3
    in <<= 1;
    in |= (INPUT_SAVE_PORT->DR & (1ul << INPUT_SAVE_PIN)) > 0 ? 1ul : 0ul;//2
    in <<= 1;
    in |= (INPUT_EXT_1_PORT->DR & (1ul << INPUT_EXT_1_PIN)) > 0 ? 1ul : 0ul;//1
    in <<= 1;
    in |= (INPUT_EXT_2_PORT->DR & (1ul << INPUT_EXT_2_PIN)) > 0 ? 1ul : 0ul;//0

    ch = in ^ lastState;
    if(ch)
    {
        lastState = in;
        same = 0 ;
        sameCheck = 1;
    }
    if(sameCheck)
    {
        if(++same >= 3)
        {
            ch = in ^ inputState;
            inputPressed = ch & inputState;
            inputJump = ch;
            inputState = in;
            sameCheck = 0 ;
            //writeKeyStatus(inputJump,inputState);
        }
    }
}


uint32_t ioState(uint32_t inputNum)
{
    return (inputState & (1ul << inputNum));
}

uint32_t ioPressed(uint32_t inputNum)
{
    uint32_t p = inputPressed & (1ul << inputNum);
    inputPressed &= ~p;
    return (p > 0) ? 1 : 0;
}

uint32_t ioJump(uint32_t inputNum)
{
    uint32_t p = inputJump & (1ul << inputNum);
    inputPressed &= ~p;
    return (p > 0) ? 1 : 0;
}

/******************************************************************************
 * @brief 静音控制
 * @param enableMute 0:关闭静音，1:开启静音
******************************************************************************/
void ioMuteCtrl(uint32_t enableMute)
{
    if(enableMute)
    {
        OUTPUT_MUTE_PORT->DR_SET = 1ul << OUTPUT_MUTE_PIN;
    }
    else
    {
        OUTPUT_MUTE_PORT->DR_CLEAR = 1ul << OUTPUT_MUTE_PIN;
    }
}

/******************************************************************************
 * @brief 继电器直通控制
 * @param enableMute 0:关闭，1:开启
******************************************************************************/
void ioRelayBypassCtrl(uint32_t enableBypass)
{
    if(enableBypass)
    {
        OUTPUT_RL_L_PORT->DR_CLEAR = 1ul << OUTPUT_RL_L_PIN;
        OUTPUT_RL_R_PORT->DR_CLEAR = 1ul << OUTPUT_RL_R_PIN;
    }
    else
    {
        OUTPUT_RL_L_PORT->DR_SET = 1ul << OUTPUT_RL_L_PIN;
        OUTPUT_RL_R_PORT->DR_SET = 1ul << OUTPUT_RL_R_PIN;
    }
}


